package cumeo89.chii.client.entry.editor;

import java.util.List;

import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.TextBoxBase;

import cumeo89.chii.client.util.MyChangeListener;
import cumeo89.chii.client.util.MyChangeListenerCollection;

public class TextEditorController implements KeyDownHandler {

	private static final TextEditorController INSTANCE = new TextEditorController();
	
	public static TextEditorController getInstance() {
		return INSTANCE;
	}
	
	private TextEditorController() {
	}

	private MyChangeListenerCollection listeners = new MyChangeListenerCollection();
	private TextBoxBase txt = null;
	private HandlerRegistration reg = null;

	public TextBoxBase getControlledText() {
		return txt;
	}

	public void registerText(TextBoxBase txt) {
		if (this.txt != txt) {
			if (this.txt != null) {
				reg.removeHandler();
			}
			this.txt = txt;
			if (txt != null) {
				reg = txt.addKeyDownHandler(this);
			} else {
				reg = null;
			}
			listeners.fireChange(this);
		}
	}

	public void unregisterText(TextBoxBase txt) {
		if (this.txt != null && this.txt == txt) {
			reg.removeHandler();
			this.txt = null;
			this.reg = null;
			listeners.fireChange(this);
		}
	}

	public void externalLink() {
		replace("[%s]", "http://www.example.com/ Văn bản liên kết");
	}

	public void internallink() {
		replace("[[%s]]", "Văn bản liên kết");
	}

	public void italic() {
		replace("''%s''", "Chữ nghiêng");
	}

	public void bold() {
		replace("'''%s'''", "Chữ đậm");
	}

	// TODO incorrect in IE
	private void replace(String format, String sample) {
		if (txt == null) {
			return;
		}
		String s = txt.getText();
		int start = txt.getCursorPos();
		int end = start + txt.getSelectionLength();
		while ((end > start) && (s.charAt(end - 1) == ' ')) {
			end--;
		}
		String inner = end > start ? s.substring(start, end) : sample;
		s = s.substring(0, start) + format.replaceFirst("%s", inner)
				+ s.substring(end);
		txt.setText(s);
		txt.setSelectionRange(start + format.indexOf("%s"), inner.length());
	}

	public void addChangeListener(MyChangeListener lis) {
		listeners.add(lis);
	}

	public void removeMyChangeListener(MyChangeListener lis) {
		listeners.remove(lis);
	}

	public List<MyChangeListener> getMyChangeListeners() {
		return listeners;
	}

	public void onKeyDown(KeyDownEvent event) {
		if (event.getSource() == txt) {
			if (event.isControlKeyDown()) {
				switch (event.getNativeKeyCode()) {
				case 'b':
				case 'B':
					bold();
					break;
				case 'i':
				case 'I':
					italic();
					break;
				case 'l':
				case 'L':
					internallink();
					break;
				case 'h':
				case 'H':
					externalLink();
					break;
				default:
					return;
				}
				event.preventDefault();
				event.stopPropagation();
			}
		}
	}

}
